package com.ux.base
{
	import com.ux.event.BLoaderEvent;
	
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.LocalConnection;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.system.SecurityDomain;
	import flash.utils.describeType;
	
	
	[Event(name="loadingProgress", type="com.ux.event.BLoaderEvent")]
	
	/**
	 * @author winnie
	 */	
	public class BLoader extends Loader
	{
		private var req : URLRequest;
		private var loadpath: String;
		
		private var _loadingPercentage : Number;
		private var _loadData : DisplayObject;
		private var _container : DisplayObjectContainer;
		
		private var _width : Number;
		private var _height : Number;
		private var _onLoadHandler : Function;
		private var _onUpdateHandler : Function;
		
		/**
		 * 
		 * @param path : 경로
		 * @param container : 로딩 완료 후 담을 컨테이너
		 * @param w : 너비
		 * @param h : 높이
		 * 
		 */		
		public function BLoader( path:String, container:DisplayObjectContainer=null, onLoadHandler:Function=null, onUpdateHandler:Function=null, w:Number=-1, h:Number=-1 )
		{
			super();
			
			if( container != null ) this._container = container;
			this.loadpath = path;
			this.req = new URLRequest();
			req.url = loadpath;
			
			if( onLoadHandler != null ) _onLoadHandler = onLoadHandler;
			if( onUpdateHandler != null ) _onUpdateHandler = onUpdateHandler;
			if( w != -1 ) this._width = w; 
			if( h != -1 ) this._height = h;
			
			this.contentLoaderInfo.addEventListener( Event.INIT, onLoadingInit );
			this.contentLoaderInfo.addEventListener( Event.COMPLETE, onLoadingComplete );
			this.contentLoaderInfo.addEventListener( IOErrorEvent.IO_ERROR, onIOErrorEvent );
			this.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onLoadingProgress );
			
			var loaderContext:LoaderContext = new LoaderContext();
			loaderContext.checkPolicyFile = true;
			loaderContext.applicationDomain = ApplicationDomain.currentDomain;

			this.load( this.req, loaderContext );
		}
		
		private function onIOErrorEvent( e:IOErrorEvent ):void
		{
			throw new Error( "BLoader onIOErrorEvent 로드중 에러발생 type : IOErrorEvent // url : " + loadpath  );
		}
		
		private function onLoadingProgress( e:ProgressEvent ):void
		{
			this._loadingPercentage = Math.floor( (e.bytesLoaded / e.bytesTotal)*100 );
			dispatchEvent( new BLoaderEvent( BLoaderEvent.PROGRESS, _loadingPercentage ) );
			if( _onUpdateHandler != null ) _onUpdateHandler();
		}
		
		private function onLoadingInit( e:Event ):void
		{
			dispatchEvent( new BLoaderEvent( BLoaderEvent.INIT ) );
			this._loadData = this.content;
			if( _width != -1 ) this._loadData.width = _width;
			if( _height != -1 ) this._loadData.height = _height;
			if( _container != null )
			{
				this._container.addChild( this );
			}
			
//			if( _onLoadHandler != null ) _onLoadHandler();
		}
		
		private function onLoadingComplete( e:Event ):void
		{
			dispatchEvent( new BLoaderEvent( BLoaderEvent.COMPLETE ) );
			if( _onLoadHandler != null ) _onLoadHandler();
		}
		
		
		/**
		 * return load Data
		 */		
		public function get loadData():DisplayObject
		{
			if( _loadData == null ) 
			{
//				throw new Error( "Loader 에서 로드되지 않은 데이터에 접근 했습니다." );
				return null;
			}
			return this._loadData;
		}
		
		/**
		 *  return loading percentage. 
		 */		
		public function get loadingPercentage():int
		{
			return _loadingPercentage;
		}
		
		/**
		 * @param _fn 로드 완료 메서드
		 */		
		public function set loadHandler( _fn : Function ):void
		{
			_onLoadHandler = _fn;
		}
		
		public function allLoadStop():void
		{
			
			this.contentLoaderInfo.removeEventListener( Event.INIT, onLoadingInit );
			this.contentLoaderInfo.removeEventListener( Event.COMPLETE, onLoadingComplete );
			this.contentLoaderInfo.removeEventListener( IOErrorEvent.IO_ERROR, onIOErrorEvent );
			this.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, onLoadingProgress );
			this.unloadAndStop();
			this.unload();
			/*
			try{
				this.close();
			}catch( e:Error )
			{
				
			}
			*/
			
			if( this.contentLoaderInfo.bytesLoaded != this.contentLoaderInfo.bytesTotal )
			{
				this.close();
			}
			
			try {
				new LocalConnection().connect('foo');
				new LocalConnection().connect('foo');
			} catch (e:*) {}

		}
		
//		override public function unloadAndStop(gc:Boolean=true):void
//		{
//			var x:XML = describeType(content);
//			
//			var len:int = x.variable.length();
//			for(var i:int; i<len; ++i)
//			{
//				if(x.variable[i].@type=="flash.display::Loader")
//				{
//					(content[x.variable[i].@name] as Loader).unloadAndStop();
//				}
//			}
//			
//			super.unloadAndStop(gc);
//		}
		
		
	}
}







